using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DigitalTrainSuite.UserControls;
using DigitalTrainSuite.Canvas;
using System.Drawing.Drawing2D;


namespace DigitalTrainSuite
{

	public partial class FormController : Form
	{
		private APIControl controller;
		private SensorDriver sensorDriver;
		private DataSetLayout data;

		private SensorMonitorForm sensorMonitorForm;

		public event EventHandler buttonDesignerClick;
		public event EventHandler buttonControllerClick;
		public event EventHandler buttonLayoutClick;

		private delegate void sensorMonitorDelegate(string display, bool append);

		private bool halted = true;	//!< true-system halted, false-system going

		public FormController(DataSetLayout data)
		{
			InitializeComponent();
			this.data = data;
			this.controller = new APIControl("com1");
			this.controller.commError += new CommErrorEventHandler(controller_commError);
			this.userControlLayout.Controller = this.controller;
			this.sensorDriver = new SensorDriver("COM2", 9600);
			this.userControlLayout.SensorNetDriver = this.sensorDriver;
			this.sensorDriver.sensorTripped += new SensorTripped(sensorDriver_sensorTripped);
			this.sensorDriver.networkMessage += new NetworkMessage(sensorDriver_networkMessage);

			this.controller.dataRecieved += new ResponseCallback(controller_dataRecieved);
			this.userControlAnyTrainController1.addControlLocomotive(this.controller.controlLocomotive);
			this.userControlAnyTrainController2.addControlLocomotive(this.controller.controlLocomotive);
			this.userControlAnyTrainController3.addControlLocomotive(this.controller.controlLocomotive);
			this.userControlAnyTrainController4.addControlLocomotive(this.controller.controlLocomotive);
			this.userControlAnyTrainController5.addControlLocomotive(this.controller.controlLocomotive);
			this.userControlAnyTrainController6.addControlLocomotive(this.controller.controlLocomotive);

			foreach (Control control in this.tabPageTrains.Controls)
			{
				if (control is UserControlAnyTrainController)
				{
					((UserControlAnyTrainController)control).Data = this.data;
				}
			}

			this.buttonStop.BackColor = Color.Red;
			this.buttonStop.Text = "STOP";
			this.halted = false;

			this.userControlLayout.Data = this.data;
			this.labelLayoutFilename.Text = Properties.Settings.Default.LayoutFilePath;
			this.userControlLayout.EnableEdit = false;
			processConnectedState();
		}

		void sensorDriver_networkMessage(string message)
		{
			this.Invoke(new sensorMonitorDelegate(setSensorMonitorText), new object[] { message, false });
		}

		void sensorDriver_sensorTripped(int sensorId, int tagId, int trainId, double speed, bool direction, bool front)
		{
			String text = String.Format("{0} of Train Sensed!" + Environment.NewLine + "Sensor ID: {1:d2}" + Environment.NewLine + "RFID Tag: 0x{2:X20}  " + "Train: 0x{5:d2}" + Environment.NewLine + "Speed: {3:f2}Kph (1:87)" + Environment.NewLine + "Direction: {4}", front ? "Front" : "Rear", sensorId, tagId, speed, direction ? "Forward" : "Backward", trainId);
			this.Invoke(new sensorMonitorDelegate(setSensorMonitorText), new object[] { text, false });
		}

		void setSensorMonitorText(string display, bool append)
		{
			if (this.sensorMonitorForm != null && !this.sensorMonitorForm.IsDisposed)
			{
				this.sensorMonitorForm.addToMonitor(display);
			}
		}

		internal void controller_commError(string message)
		{
			MessageBox.Show(message, "Communication Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
		}

		private void processConnectedState()
		{
			if (this.controller == null || !this.controller.Connected)
			{

				this.toolStripMenuItemDisconnect.Enabled = false;
				this.toolStripMenuItemConnect.Enabled = true;
				this.notifyIconDisconnected.Visible = true;
				this.buttonConnectDisconnect.Text = "Connect";

				this.buttonStop.Enabled = false;
				this.userControlLayout.EnableControls = false;

				foreach (Control control in this.tabPageTrains.Controls)
				{
					if (control is UserControlAnyTrainController)
					{
						((UserControlAnyTrainController)control).Enabled = false;
					}
				}
			}
			else
			{
				this.toolStripMenuItemDisconnect.Enabled = true;
				this.toolStripMenuItemConnect.Enabled = false;
				this.notifyIconDisconnected.Visible = false;
				this.buttonConnectDisconnect.Text = "Disconnect";

				this.buttonStop.Enabled = true;
				this.userControlLayout.EnableControls = true;
				foreach (Control control in this.tabPageTrains.Controls)
				{
					if (control is UserControlAnyTrainController)
					{
						((UserControlAnyTrainController)control).Enabled = true;
					}
				}
			}
		}

		void controller_dataRecieved(string response)
		{
			Console.WriteLine(response);
		}

		private void buttonStop_Click(object sender, EventArgs e)
		{

			if (halted == false)
			{
				this.buttonStop.BackColor = Color.Green;
				this.buttonStop.Text = "GO";
				this.controller.halt();
				halted = true;
				this.userControlLayout.EnableControls = false;
			}
			else if(halted == true)
			{
				this.buttonStop.BackColor = Color.Red;
				this.buttonStop.Text = "STOP";
				this.controller.release();
				halted = false;
				this.userControlLayout.EnableControls = true;
			}

		}

		private void FormController_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (this.sensorMonitorForm != null) this.sensorMonitorForm.Dispose();
			this.controller.Dispose();
			this.sensorDriver.Dispose();
			this.notifyIconDisconnected.Visible = false;
		}

		private void toolStripMenuItemConnect_Click(object sender, EventArgs e)
		{
			if (this.controller.Connected) return;
			else
			{
				this.controller.connect();
				this.processConnectedState();
			}
		}

		private void toolStripMenuItemDisconnect_Click(object sender, EventArgs e)
		{
			if (!this.controller.Connected) return;
			else
			{
				this.controller.disconnect();
				this.processConnectedState();
			}
		}

		private void buttonConnectDisconnect_Click(object sender, EventArgs e)
		{
			if (this.controller.Connected)
			{
				this.controller.disconnect();
			}
			else
			{
				this.controller.connect();
			}
			this.processConnectedState();
		}

		private void buttonSave_Click(object sender, EventArgs e)
		{
			this.saveLayout();
		}

		public void saveLayout()
		{
			this.data.TurnoutControl.Clear();
			this.data.RFIDSensor.Clear();
			this.userControlLayout.saveLayout(this.data);
			this.data.WriteXml(this.labelLayoutFilename.Text);
		}

		public void saveLayout(string filename)
		{
			this.data.TurnoutControl.Clear();
			this.data.RFIDSensor.Clear();
			this.userControlLayout.saveLayout(this.data);
			this.data.WriteXml(filename);
			this.labelLayoutFilename.Text = filename;
		}

		public void openLayout(string filename)
		{
			this.data.Clear();
			this.data.ReadXml(filename);
			this.userControlLayout.loadLayout();
			this.labelLayoutFilename.Text = filename;
			this.processConnectedState();
		}

		private void buttonOpen_Click(object sender, EventArgs e)
		{
			this.openFileDialog.ShowDialog();
		}

		private void openFileDialog_FileOk(object sender, CancelEventArgs e)
		{
			this.openLayout(this.openFileDialog.FileName);
		}

		private void checkBoxEdit_CheckedChanged(object sender, EventArgs e)
		{
			this.userControlLayout.EnableEdit = this.checkBoxEdit.Checked;
		}

		private void checkBoxViewAddresses_CheckedChanged(object sender, EventArgs e)
		{
			this.userControlLayout.ViewAddresses = this.checkBoxViewAddresses.Checked;
		}

		private void buttonDesigner_Click(object sender, EventArgs e)
		{
			if (this.buttonDesignerClick != null)
			{
				this.buttonDesignerClick(sender, e);
			}
		}

		private void buttonSaveAs_Click(object sender, EventArgs e)
		{
			this.saveFileDialog.ShowDialog();
		}

		private void saveFileDialog_FileOk(object sender, CancelEventArgs e)
		{
			this.saveLayout(this.saveFileDialog.FileName);
        }

      

        #region Control Form Coloring 
        private void panelMain_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            LinearGradientBrush backColorBrush;
            Rectangle panelMainRectangle = new Rectangle(0, 0, panelMain.Size.Width, panelMain.Size.Height);

            backColorBrush = new LinearGradientBrush(panelMainRectangle, Properties.Settings.Default.FormBackColor, Color.LightGray, LinearGradientMode.Vertical);
            g.FillRectangle(backColorBrush, panelMainRectangle);

        }

        private void flowLayoutPanelLayout_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Rectangle tabPageRectangle = new Rectangle(0, 0, this.flowLayoutPanelLayout.Size.Width, this.flowLayoutPanelLayout.Size.Height);
            LinearGradientBrush backColorBrush;

            backColorBrush = new LinearGradientBrush(tabPageRectangle, Properties.Settings.Default.TabsPageColor, Color.White, LinearGradientMode.ForwardDiagonal);
            g.FillRectangle(backColorBrush, tabPageRectangle);

        }




        #endregion

		private void userControlAnyTrainController1_Load(object sender, EventArgs e)
		{

		}

		private void buttonOpenMonitor_Click(object sender, EventArgs e)
		{
			if (this.sensorMonitorForm == null || this.sensorMonitorForm.IsDisposed)
			{
				this.sensorMonitorForm = new SensorMonitorForm();
			}
			this.sensorMonitorForm.Show();
			this.sensorMonitorForm.Focus();
		}

		private void buttonResetSensors_Click(object sender, EventArgs e)
		{
			this.sensorDriver.sendStartup();
		}

       

       
    }
}